package com.trade.system.security;

import com.trade.module.base.entity.Role;
import com.trade.module.base.entity.User;
import com.trade.module.base.service.RoleService;
import com.trade.module.base.service.UserService;
import com.trade.common.utils.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.*;

/**
 * Class Description:
 *
 * @Version v1.0 2017/4/21 22:57
 * @JDK version 1.8.0_51
 * @Author zfb
 */
@Component
public class CustomUserDetailsService implements UserDetailsService {

    /**
     * 日志类型声明
     **/
    private static final Logger logs = LoggerFactory.getLogger(CustomUserDetailsService.class);

    /**
     * 用户服务类
     **/
    @Autowired
    private UserService userService;

    /**
     * 角色服务类
     **/
    @Autowired
    private RoleService roleService;

    /**
     * session管理
     **/
    @Autowired
    private SpringSessionRegistry sessionRegistry;

    /**
     * 加載用戶信息
     *
     * @param username 用户名称
     * @return UserDetails 用户详情
     * @throws UsernameNotFoundException 用户名未发现
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //user对应数据库中的用户表，是最终存储用户和密码的表，可自定义
        User user = userService.findByAccountAndUserFlagAndDataFlag(username, Constants.USER_FLAG_USERED,
                Constants.DATA_FLAG_OK);
        if (null == user) {
            throw new UsernameNotFoundException("username " + username + " not found!");
        }
        /*
         * description：
         *      1、根据传入的用户名称去数据库中查找该用户信息
         *      2、从session中获取该用户的所有session信息
         *      3、如果有对应的用户的session，将其设置为过期失效
         */
        List<Object> objects = this.sessionRegistry.getAllPrincipals();
        if(null!=objects && objects.size()>0){
            for(Object obj : objects){
                User authUser = (User) obj;
                if(authUser.getAccount().equals(user.getAccount())){
                    //未失效的会话集合
                    List<SessionInformation> sessions = this.sessionRegistry.getAllSessions(
                            authUser,false);
                    if(sessions!=null){
                        for(SessionInformation session:sessions){
                            //设置session过期
                            session.expireNow();
                            //如果已经过期，则删除该用户的session信息
                            //if(si.isExpired()){
                            //    this.sessionRegistry.removeSessionInformation(si.getSessionId());
                            //    logs.info(authUser.getAccount() + "重新登录到系统！");
                            //}
                        }
                    } else {
                        logs.info("该用户（"+user.getAccount()+"）没有失效的会话！");
                    }
                    break;
                }
            }
        }

        Iterable<Role> userRoles = roleService.findRoleByUserId(user.getId());
        Set<Role> roleSet = new HashSet<>();
        if (null!=userRoles){
            for (Role userRole : userRoles) {
                roleSet.add(userRole);
            }
        }

        List<String> dbRoles = new ArrayList<>();
        for(Role r : roleSet){
            dbRoles.add(r.getRoleCode());
        }
        dbRoles.add("ROLE_SUPER_ADMIN");
        return new SecurityUser(user,dbRoles);
    }
}
